package trading.util;

import java.util.HashMap;
import java.util.Map;

import trading.bo.DBAccessorBO;

public class IBMsgIDGen {

    private int DEFAULT_MESSAGE_ID = 0;
    private Integer currentMessageId = null;
    private IBMsgBean currentMsgBean = null;
    private Map<Integer, IBMsgBean> activeMsgBeans = null;
    

    private DBAccessorBO dbAccessBO;

    public void setDbAccessorBO(DBAccessorBO dbAccessorBO) {
        this.dbAccessBO = dbAccessorBO;
        this.DEFAULT_MESSAGE_ID = this.dbAccessBO.getHighestOrderId() + 1;
    }

    public enum IBMsgType {
        LATEST_PRICE, HISTORICAL_LOW_PRICE_DATE, MARKET_STATUS, LAST_CLOSE_PRICE, LAST_CLOSE_FUTURE_PRICE, CURRENT_FUTURE_PRICE, CURRENT_OPTION_PRICE, CONNECTION;
    };

    public class IBMsgBean {
        private int id;
        private IBMsgType msgType;
        private Map<String, String> otherInfo;

        public IBMsgBean(int id, IBMsgType msgType,
                Map<String, String> otherInfo) {
            this.id = id;
            this.msgType = msgType;
            this.otherInfo = otherInfo;
        }

        public int getId() {
            return id;
        }

        public IBMsgType getMsgType() {
            return msgType;
        }

        public Map<String, String> getOtherInfo() {
            return otherInfo;
        }
    }

    public IBMsgBean getNextBean(IBMsgType msgType,
            Map<String, String> otherInfo) {
        if (currentMessageId == null) {
            currentMessageId = DEFAULT_MESSAGE_ID;
        } else {
            currentMessageId++;
        }
        currentMsgBean = new IBMsgBean(currentMessageId, msgType, otherInfo);
        if (activeMsgBeans == null) {
            activeMsgBeans = new HashMap<Integer, IBMsgBean>();
        }
        activeMsgBeans.put(currentMessageId, currentMsgBean);
        return currentMsgBean;
    }

    /**
     * For snapshot, the id is for one time use.
     * 
     * @return
     */
    public IBMsgBean getNextSnapshotBean(IBMsgType msgType,
            Map<String, String> otherInfo) {
        int retVal;
        if (currentMessageId == null) {
            retVal = DEFAULT_MESSAGE_ID;
        } else {
            retVal = currentMessageId + 1;
        }

        currentMsgBean = new IBMsgBean(retVal, msgType, otherInfo);
        return currentMsgBean;
    }

    public Map<Integer, IBMsgBean> getActiveBeans() {
        return this.activeMsgBeans;
    }

    public IBMsgBean getCurrentMsgBean() {
        return currentMsgBean;
    }

    public IBMsgBean getMsgBean(int id) {
        return activeMsgBeans.get(id);
    }

    public void releaseActiveMsgBean(int id) {
        activeMsgBeans.remove(id);
    }

    /**
     * For request to place new orders, we don't need a message bean, but we do
     * need a unique id.
     * 
     * @return
     */
    public int getNewMsgID() {
        if (currentMessageId == null) {
            currentMessageId = DEFAULT_MESSAGE_ID;
        } else {
            currentMessageId++;
        }
        return currentMessageId;
    }

    public void releaseCurrentMsgBean() {
        this.activeMsgBeans.remove(this.currentMessageId);
        if (currentMsgBean != null) {
            currentMsgBean = null;
            currentMessageId--;
        }
    }

}
